/**
 * HTTP 请求工具类
 */
import { getBaseUrl, API_CONFIG, HTTP_STATUS, BUSINESS_CODE, REQUEST_HEADERS } from './config.js'
import { getToken, removeToken } from './auth.js'

/**
 * 请求拦截器
 */
const requestInterceptor = (options) => {
  // 设置基础 URL
  options.url = getBaseUrl() + options.url

  // 设置请求头
  options.header = {
    ...REQUEST_HEADERS,
    ...options.header
  }

  // 添加认证 token
  const token = getToken()
  if (token) {
    options.header.Authorization = `Bearer ${token}`
  }

  // 设置超时时间
  options.timeout = options.timeout || API_CONFIG.TIMEOUT

  console.log('请求拦截器:', options)
  return options
}

/**
 * 响应拦截器
 */
const responseInterceptor = (response, options) => {
  console.log('响应拦截器:', response)

  const { statusCode, data } = response

  // HTTP 状态码检查
  if (statusCode !== HTTP_STATUS.OK) {
    handleHttpError(statusCode, data, options)

    // 对于登录请求，创建一个包含详细错误信息的错误对象
    if (options.isLoginRequest) {
      const error = {
        code: statusCode,
        message: data && data.message ? data.message : '用户名或密码错误',
        data: data
      }
      return Promise.reject(error)
    }

    return Promise.reject(response)
  }

  // 业务状态码检查
  if (data && data.code !== undefined) {
    if (data.code === BUSINESS_CODE.SUCCESS) {
      return data
    } else {
      handleBusinessError(data.code, data.message, options)
      return Promise.reject(data)
    }
  }

  // 如果没有业务状态码，直接返回数据
  return data
}

/**
 * 处理 HTTP 错误
 */
const handleHttpError = (statusCode, data, options) => {
  let message = '请求失败'

  switch (statusCode) {
    case HTTP_STATUS.BAD_REQUEST:
      message = '请求参数错误'
      break
    case HTTP_STATUS.UNAUTHORIZED:
      // 如果是登录请求失败，不自动跳转，让页面自己处理错误
      if (options.isLoginRequest) {
        message = data && data.message ? data.message : '用户名或密码错误'
      } else {
        message = '登录已过期，请重新登录'
        handleUnauthorized()
      }
      break
    case HTTP_STATUS.FORBIDDEN:
      message = '没有权限访问'
      break
    case HTTP_STATUS.NOT_FOUND:
      message = '请求的资源不存在'
      break
    case HTTP_STATUS.INTERNAL_SERVER_ERROR:
      message = '服务器内部错误'
      break
    default:
      message = `请求失败 (${statusCode})`
  }

  // 显示错误提示（登录请求的错误由页面自己处理）
  if (!options.silent && !options.isLoginRequest) {
    uni.showToast({
      title: message,
      icon: 'none',
      duration: 2000
    })
  }
}

/**
 * 处理业务错误
 */
const handleBusinessError = (code, message, options) => {
  if (code === BUSINESS_CODE.UNAUTHORIZED) {
    // 如果是登录请求失败，不自动跳转
    if (!options.isLoginRequest) {
      handleUnauthorized()
    }
    return
  }

  // 显示错误提示
  if (!options.silent && message) {
    uni.showToast({
      title: message,
      icon: 'none',
      duration: 2000
    })
  }
}

/**
 * 处理未授权错误
 */
const handleUnauthorized = () => {
  // 清除 token
  removeToken()

  // 跳转到登录页
  uni.reLaunch({
    url: '/pages/login/login'
  })
}

/**
 * 发起请求
 */
const request = (options) => {
  return new Promise((resolve, reject) => {
    // 请求拦截
    const interceptedOptions = requestInterceptor(options)

    // 发起请求
    uni.request({
      ...interceptedOptions,
      success: (response) => {
        try {
          const result = responseInterceptor(response, options)
          resolve(result)
        } catch (error) {
          reject(error)
        }
      },
      fail: (error) => {
        console.error('请求失败:', error)

        if (!options.silent) {
          uni.showToast({
            title: '网络请求失败',
            icon: 'none',
            duration: 2000
          })
        }

        reject(error)
      }
    })
  })
}

/**
 * GET 请求
 */
export const get = (url, params = {}, options = {}) => {
  return request({
    url,
    method: 'GET',
    data: params,
    ...options
  })
}

/**
 * POST 请求
 */
export const post = (url, data = {}, options = {}) => {
  return request({
    url,
    method: 'POST',
    data,
    ...options
  })
}

/**
 * PUT 请求
 */
export const put = (url, data = {}, options = {}) => {
  return request({
    url,
    method: 'PUT',
    data,
    ...options
  })
}

/**
 * DELETE 请求
 */
export const del = (url, data = {}, options = {}) => {
  return request({
    url,
    method: 'DELETE',
    data,
    ...options
  })
}

/**
 * 文件上传
 */
export const upload = (url, filePath, formData = {}, options = {}) => {
  return new Promise((resolve, reject) => {
    const token = getToken()

    // 支持自定义文件字段名，默认为 'file'
    const fileName = options.name || 'file'

    uni.uploadFile({
      url: getBaseUrl() + url,
      filePath,
      name: fileName,
      formData,
      header: {
        Authorization: token ? `Bearer ${token}` : ''
      },
      success: (response) => {
        try {
          const data = JSON.parse(response.data)
          if (data.code === BUSINESS_CODE.SUCCESS) {
            resolve(data)
          } else {
            reject(data)
          }
        } catch (error) {
          reject(error)
        }
      },
      fail: (error) => {
        console.error('文件上传失败:', error)
        reject(error)
      }
    })
  })
}

export default request
